package tmt.usercenter.web.service;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tmt.usercenter.web.domain.enums.SystemParamCode;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

/**
 * 作者：ThreeManTeam
 * 创建时间：2019-08-21 09:28
 */
@Service
public class LoginAttemptService {

    public static final String ALLOWED_LOGIN_ATTEMPT_COUNT = "ALLOWED_LOGIN_ATTEMPT_COUNT";

    public static final String MINUTES_FOR_ALLOWED_LOGIN_ATTEMPT_COUNT = "MINUTES_FOR_ALLOWED_LOGIN_ATTEMPT_COUNT";

    @Autowired
    private SystemParamService paramService;

    private LoadingCache<String, Integer> attemptsCache;

    public LoginAttemptService() {
        super();
        int minutes = getMinutesForMaxAllowedLoginCount();
        attemptsCache = CacheBuilder.newBuilder().expireAfterWrite(minutes, TimeUnit.MINUTES).build(new CacheLoader<String, Integer>() {
            public Integer load(String key) {
                return 0;
            }
        });
    }

    public void loginSucceeded(String key) {
        attemptsCache.invalidate(key);
    }

    public void loginFailed(String key) {
        int attempts = 0;
        try {
            attempts = attemptsCache.get(key);
        } catch (ExecutionException e) {
            attempts = 0;
        }
        attempts++;
        attemptsCache.put(key, attempts);
    }

    public int getAllowedLoginCount(String key) {
        int count = getMaxAllowedLoginCount();
        int curCount = 0;
        try {
            boolean exists = attemptsCache.asMap().containsKey(key);
            curCount = exists ? attemptsCache.get(key) : 0;
        } catch (Exception ex) {
        }
        return Math.max(0, count - 1 - curCount);
    }

    public boolean isBlocked(String key) {
        try {
            int count = getMaxAllowedLoginCount();
            return attemptsCache.get(key) >= count;
        } catch (ExecutionException e) {
            return false;
        }
    }

    public int getMinutesForMaxAllowedLoginCount() {
        int count = 30;
        try {
            String config = paramService.getSystemParamValue(SystemParamCode.MAX_LOGIN_ATTEMPT_COUNT);
            String[] subConfig = config.split(">");
            if (subConfig.length > 0) {
                count = Integer.parseInt(subConfig[0]);
            }
        } catch (Exception e) {
        }
        return count;
    }

    private int getMaxAllowedLoginCount() {
        int count = 5;
        try {
            String config = paramService.getSystemParamValue(SystemParamCode.MAX_LOGIN_ATTEMPT_COUNT);
            String[] subConfig = config.split(">");
            if (subConfig.length > 1) {
                count = Integer.parseInt(subConfig[1]);
            }
        } catch (Exception e) {
        }
        return count;
    }
}
